package com.imis.module.online.table.bus;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.imis.base.constant.CommonConstant;
import com.imis.base.constant.ControlTypeConstant;
import com.imis.base.constant.DataBaseConstant;
import com.imis.base.constant.enums.ButtonCodeEnum;
import com.imis.base.globle.response.BaseResponse;
import com.imis.base.globle.response.CommonResponse;
import com.imis.base.util.ConvertUtils;
import com.imis.base.util.form.EnhanceJavaScriptUtil;
import com.imis.base.util.form.EnhanceJavaUtil;
import com.imis.base.util.form.FormUtil;
import com.imis.base.util.form.model.LinkDown;
import com.imis.module.api.model.ro.DictItemsQueryDTO;
import com.imis.module.base.BaseBus;
import com.imis.module.base.SortField;
import com.imis.module.online.form.model.converter.FormButtonConverter;
import com.imis.module.online.form.model.converter.FormEnhanceJavaConverter;
import com.imis.module.online.form.model.converter.FormEnhanceJavaScriptConverter;
import com.imis.module.online.form.model.converter.FormEnhanceStructuredQueryLanguageConverter;
import com.imis.module.online.form.model.po.FormButton;
import com.imis.module.online.form.model.po.FormEnhanceJava;
import com.imis.module.online.form.model.po.FormEnhanceJavaScript;
import com.imis.module.online.form.model.po.FormEnhanceStructuredQueryLanguage;
import com.imis.module.online.form.service.IFormButtonService;
import com.imis.module.online.form.service.IFormEnhanceJavaScriptService;
import com.imis.module.online.form.service.IFormEnhanceJavaService;
import com.imis.module.online.form.service.IFormEnhanceStructuredQueryLanguageService;
import com.imis.module.online.table.model.converter.TableFieldsConverter;
import com.imis.module.online.table.model.converter.TableHeadConverter;
import com.imis.module.online.table.model.po.TableFields;
import com.imis.module.online.table.model.po.TableHead;
import com.imis.module.online.table.model.ro.DataAddDTO;
import com.imis.module.online.table.model.ro.DataUpdateDTO;
import com.imis.module.online.table.model.ro.PagingQueryDataDTO;
import com.imis.module.online.table.model.vo.DataPageFieldVO;
import com.imis.module.online.table.model.vo.DataQueryConditionsFieldVO;
import com.imis.module.online.table.model.vo.ListPageElementVO;
import com.imis.module.online.table.model.vo.TableFieldsVO;
import com.imis.module.online.table.service.ITableFieldsService;
import com.imis.module.online.table.service.ITableHeadService;
import com.imis.module.online.table.service.ITableIndexService;
import com.imis.module.system.model.converter.SysDictConverter;
import com.imis.module.system.model.vo.DictVO;
import com.imis.module.system.service.ISysDictService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * <p>
 * 在线开发-数据库API 业务处理类
 * </p>
 *
 * @author XinLau
 * @since 2020-10-03
 */
@Slf4j
@Service
public class FormApiBus extends BaseBus {

    /**
     * 在线开发-数据库表表信息 服务类
     */
    private ITableHeadService serviceByTableHeadService;

    @Autowired
    public void setTableHeadService(ITableHeadService serviceByTableHeadService) {
        this.serviceByTableHeadService = serviceByTableHeadService;
    }

    /**
     * 在线开发-数据库表字段信息 服务类
     */
    private ITableFieldsService serviceByTableFieldsService;

    @Autowired
    public void setTableFieldsService(ITableFieldsService serviceByTableFieldsService) {
        this.serviceByTableFieldsService = serviceByTableFieldsService;
    }

    /**
     * 在线开发-数据库表索引 服务类
     */
    private ITableIndexService serviceByTableIndexService;

    @Autowired
    public void setTableIndexService(ITableIndexService serviceByTableIndexService) {
        this.serviceByTableIndexService = serviceByTableIndexService;
    }

    /**
     * 在线开发-表单按钮 服务类
     */
    private IFormButtonService serviceByFormButtonService;

    @Autowired
    public void setFormButtonService(IFormButtonService serviceByFormButtonService) {
        this.serviceByFormButtonService = serviceByFormButtonService;
    }

    /**
     * 在线开发-Java增强 服务类
     */
    private IFormEnhanceJavaService serviceByFormEnhanceJavaService;

    @Autowired
    public void setFormEnhanceJavaService(IFormEnhanceJavaService serviceByFormEnhanceJavaService) {
        this.serviceByFormEnhanceJavaService = serviceByFormEnhanceJavaService;
    }

    /**
     * 在线开发-JavaScript 增强 服务类
     */
    private IFormEnhanceJavaScriptService serviceByFormEnhanceJavaScriptService;

    @Autowired
    public void setFormEnhanceJavaScriptService(IFormEnhanceJavaScriptService serviceByFormEnhanceJavaScriptService) {
        this.serviceByFormEnhanceJavaScriptService = serviceByFormEnhanceJavaScriptService;
    }

    /**
     * 在线开发-SQL增强 服务类
     */
    private IFormEnhanceStructuredQueryLanguageService serviceByFormEnhanceStructuredQueryLanguageService;

    @Autowired
    public void setFormEnhanceStructuredQueryLanguageService(IFormEnhanceStructuredQueryLanguageService serviceByFormEnhanceStructuredQueryLanguageService) {
        this.serviceByFormEnhanceStructuredQueryLanguageService = serviceByFormEnhanceStructuredQueryLanguageService;
    }

    /**
     * 字典项 服务类
     */
    private ISysDictService serviceBySysDictService;

    @Autowired
    public void setServiceBySysDictService(ISysDictService serviceBySysDictService) {
        this.serviceBySysDictService = serviceBySysDictService;
    }

    /**
     * 获取列表页面元素接口
     *
     * @param listPageElement                   - 分页查询列表页面元素对象
     * @param tableFieldPermissionFilteringList - 权限过滤后的 数据库表字段信息
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2021/1/11 11:07
     */
    private void getListPageTableFieldElement(ListPageElementVO listPageElement, final List<TableFields> tableFieldPermissionFilteringList) {
        // 查询条件字段
        List<DataQueryConditionsFieldVO> queryConditionsList = new LinkedList<>();
        // 列表显示字段
        List<DataPageFieldVO> listDisplayFieldList = new LinkedList<>();
        // 下拉字典信息
        Map<String, List<DictVO>> dictOptions = new HashMap<>(16);
        tableFieldPermissionFilteringList.forEach(tableFields -> {
            // 4.1构建 查询条件字段 对象
            if (CommonConstant.INTEGER_YES.equals(tableFields.getIsQuery())) {
                DataQueryConditionsFieldVO dataQueryConditionsField = TableFieldsConverter.INSTANCE.getDataQueryConditionsField(tableFields);
                queryConditionsList.add(dataQueryConditionsField);
            }
            // 4.2构建 列表显示字段 对象
            if (CommonConstant.INTEGER_YES.equals(tableFields.getIsShowList())) {
                DataPageFieldVO dataPageField = new DataPageFieldVO();
                // TODO:This
                listDisplayFieldList.add(dataPageField);
            }
            String viewCode = tableFields.getFieldShowType();
            String fieldName = tableFields.getFieldName();
            // 4.3构建 下拉字典数据 对象
            if (ConvertUtils.isNotEmpty(tableFields.getDictField()) && !ControlTypeConstant.POPUP.equals(viewCode)) {
                List<DictVO> dictList = new ArrayList<>();
                // 普通字典 + 表字典
                if (ConvertUtils.isNotEmpty(tableFields.getDictTable())) {
                    DictItemsQueryDTO sysDictItemsQuery = new DictItemsQueryDTO();
                    sysDictItemsQuery.setTable(tableFields.getDictTable());
                    sysDictItemsQuery.setTextField(tableFields.getDictText());
                    sysDictItemsQuery.setCodeField(tableFields.getDictField());
                    dictList = serviceBySysDictService.queryTableDictItemsByParameter(sysDictItemsQuery);
                } else if (ConvertUtils.isNotEmpty(tableFields.getDictField())) {
                    dictList = serviceBySysDictService.queryDictItemsByDictCode(tableFields.getDictField());
                }
                dictOptions.put(fieldName, dictList);
            }
            // 4.4构建 级联下拉字典数据 对象
            if (ControlTypeConstant.LINK_DOWN.equals(viewCode)) {
                String jsonString = tableFields.getDictTable();
                LinkDown linkDown = JSONObject.parseObject(jsonString, LinkDown.class);
                DictItemsQueryDTO sysDictItemsQuery = new DictItemsQueryDTO();
                sysDictItemsQuery.setTable(linkDown.getDictTable());
                sysDictItemsQuery.setTextField(linkDown.getDictText());
                sysDictItemsQuery.setCodeField(linkDown.getDictField());
                sysDictItemsQuery.setFilterSql(linkDown.getConditionSql());
                List<DictVO> dictList = serviceBySysDictService.queryTableDictItemsByParameter(sysDictItemsQuery);
                dictOptions.put(fieldName, dictList);
            }
            // 4.5构建 树控件 对象
            if (ControlTypeConstant.SELECT_TREE.equals(viewCode)) {
                String[] colsInfo = tableFields.getDictText().split(CommonConstant.COMMA);
                DictItemsQueryDTO sysDictItemsQuery = new DictItemsQueryDTO();
                sysDictItemsQuery.setTable(tableFields.getDictTable());
                sysDictItemsQuery.setTextField(colsInfo[2]);
                sysDictItemsQuery.setCodeField(colsInfo[0]);
                List<DictVO> dictList = serviceBySysDictService.queryTableDictItemsByParameter(sysDictItemsQuery);
                dictOptions.put(fieldName, dictList);
            }
            if (ControlTypeConstant.DICT_TREE.equals(viewCode)) {
                // 分类字典树控件
                String dictText = tableFields.getDictText();
                if (ConvertUtils.isEmpty(dictText)) {
                    // 只存了id 需要在前端翻译
                    String filterSql = FormUtil.getCategoryConditionStructuredQueryLanguage(tableFields.getDictField());
                    // TODO:This
                    List<DictVO> dictList = new ArrayList<>();
                    dictOptions.put(fieldName, dictList);
                }
            }
        });
        // 下拉字典数据
        listPageElement.setDictOptions(dictOptions);
        // 数据查询条件字段列表
        listPageElement.setDataQueryConditionsFieldList(queryConditionsList);
        // 数据页列表字段
        listPageElement.setDataPageFieldList(listDisplayFieldList);
    }

    /**
     * 表单数据验证
     *
     * @param tableFieldsList - 数据库表字段信息
     * @param tableDataJson   - 数据库表表单数据
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private void formDataVerification(final List<TableFields> tableFieldsList, final JSONObject tableDataJson) {
        for (TableFields tableField : tableFieldsList) {
            // 字段名字
            String fieldName = tableField.getFieldName();
            // 是否允许为空（0否 1是）
            Integer isNull = tableField.getIsNull();
            if (CommonConstant.INTEGER_NO.equals(isNull)) {
                String value = tableDataJson.getString(fieldName);
                assertThat(value).as("数据库表非空字段获取表单数据").isNotBlank().isNotEmpty().isNotNull();
            }
        }
    }

    /**
     * 数据库表数据校验
     *
     * @param tableHead       - 数据库表表对象
     * @param tableFieldsList - 数据库表字段信息
     * @param tableDataJson   - 数据库表表单数据
     * @return Result<?>
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private void formDataVerification(final TableHead tableHead, final List<TableFields> tableFieldsList, final JSONObject tableDataJson) {
        formDataVerification(tableFieldsList, tableDataJson);
        if (CommonConstant.TABLE_TYPE_1.equals(tableHead.getTableType())) {
            // 如果是主表 验证子表的数据
            String subTables = tableHead.getSubTableCheckList();
            // 判断一下防止空指针
            if (ConvertUtils.isNotEmpty(subTables)) {
                for (String subTableName : subTables.split(CommonConstant.COMMA)) {
                    JSONArray jsonArray = tableDataJson.getJSONArray(subTableName);
                    if (jsonArray == null || jsonArray.isEmpty()) {
                        continue;
                    }
                    // 数据库表表信息
                    TableHead subTableHead = this.serviceByTableHeadService.getOne(new LambdaQueryWrapper<TableHead>().eq(TableHead::getTableName, subTableName));
                    if (subTableHead == null) {
                        continue;
                    }
                    // 数据库表字段信息
                    List<TableFields> subTableFieldList = this.serviceByTableFieldsService.list(new LambdaQueryWrapper<TableFields>().eq(TableFields::getTableHeadId, subTableHead.getId()));
                    formDataVerification(subTableFieldList, tableDataJson);
                }
            }
        }
    }

    /**
     * 数据库表数据新增校验
     *
     * @param dataAdd         - 数据库表数据新增对象
     * @param tableHead       - 数据库表表对象
     * @param tableFieldsList - 数据库表字段信息
     * @return Result<?>
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private void addTableDataVerification(final DataAddDTO dataAdd, final TableHead tableHead, final List<TableFields> tableFieldsList) {
        // TODO:This 添加校验
        // 数据库表表-是否非空
        assertThat(tableHead).as("在线开发-数据库表表信息").isNotNull();
        // 数据库表字段信息
        assertThat(tableFieldsList).as("数据库表字段信息数据库表字段信息").isNotEmpty().isNotNull();
        // 数据库表表单数据
        JSONObject tableDataJson = dataAdd.getTableDataJson();
        formDataVerification(tableHead, tableFieldsList, tableDataJson);
    }

    /**
     * 数据库表数据更新校验
     *
     * @param dataUpdate      - 数据库表数据更新对象
     * @param tableHead       - 数据库表表对象
     * @param tableFieldsList - 数据库表字段信息
     * @return Result<?>
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private void updateTableDataVerification(final DataUpdateDTO dataUpdate, final TableHead tableHead, final List<TableFields> tableFieldsList) {
        // TODO:This 修改校验
        // 数据库表表单数据
        JSONObject tableDataJson = dataUpdate.getTableDataJson();
        Long dataId = tableDataJson.getLong(DataBaseConstant.P_KEY);
        assertThat(dataId).as("数据库表表单数据主键").isNotNull();
        // 数据库表表-是否非空
        assertThat(tableHead).as("在线开发-数据库表表信息").isNotNull();
        // 数据库表字段信息
        assertThat(tableFieldsList).as("数据库表字段信息数据库表字段信息").isNotEmpty().isNotNull();
        formDataVerification(tableHead, tableFieldsList, tableDataJson);
    }

    /**
     * 保存数据库表数据
     *
     * @param tableName      - 数据库表名称
     * @param tableFieldList - 数据库表字段信息
     * @param tableDataJson  - 数据库表数据
     * @return Boolean -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private void saveFormData(final String tableName, final List<TableFields> tableFieldList, final JSONObject tableDataJson) {
        // tableDataJson.put(DataBaseConstant.P_KEY, IdWorker.getId());
        Map<String, Object> params = FormUtil.getFormDataSaveStructuredQueryLanguage(tableName, tableFieldList, tableDataJson);
        Boolean save = this.serviceByTableIndexService.executeInsertStructuredQueryLanguage(params);
        assertThat(Boolean.TRUE).as("保存数据库表数据").isEqualTo(save).isTrue();
    }

    /**
     * 保存子表的数据
     *
     * @param tableHead     - 主表数据库表表信息
     * @param tableDataJson - 数据库表数据
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private void saveTheDataOfTheChildTable(final TableHead tableHead, final JSONObject tableDataJson) {
        // 如果是主表 还需要保存子表的数据
        String subTables = tableHead.getSubTableCheckList();
        // 判断一下防止空指针
        if (ConvertUtils.isNotEmpty(subTables)) {
            for (String subTableName : subTables.split(CommonConstant.COMMA)) {
                JSONArray jsonArray = tableDataJson.getJSONArray(subTableName);
                if (jsonArray == null || jsonArray.isEmpty()) {
                    continue;
                }
                // 数据库表表信息
                TableHead subTableHead = this.serviceByTableHeadService.getOne(new LambdaQueryWrapper<TableHead>().eq(TableHead::getTableName, subTableName));
                if (subTableHead == null) {
                    continue;
                }
                // 数据库表字段信息
                List<TableFields> subTableFieldList = this.serviceByTableFieldsService.list(new LambdaQueryWrapper<TableFields>().eq(TableFields::getTableHeadId, subTableHead.getId()));
                // 这里有一步非常重要 需要获取子表字段对应设置外键的那个字段然后赋值
                String subLinkField = "",
                        subLinkValue = null;
                for (TableFields subTableField : subTableFieldList) {
                    if (ConvertUtils.isEmpty(subTableField.getMainField())) {
                        continue;
                    }
                    subLinkField = subTableField.getFieldName();
                    String mainField = subTableField.getMainField();
                    // 主子表关联字段取值， 做出 KEY 忽略大小写
                    if (tableDataJson.get(mainField.toLowerCase()) != null) {
                        // 小写
                        subLinkValue = tableDataJson.getString(mainField.toLowerCase());
                    }
                    if (tableDataJson.get(mainField.toUpperCase()) != null) {
                        // 大写
                        subLinkValue = tableDataJson.getString(mainField.toUpperCase());
                    }
                }
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    if (subLinkValue != null) {
                        // 设置外键值
                        jsonObject.put(subLinkField, subLinkValue);
                    }
                    this.saveFormData(subTableName, subTableFieldList, jsonObject);
                }
            }
        }
    }

    /**
     * 更新子表的数据
     *
     * @param tableHead     - 主表数据库表表信息
     * @param tableDataJson - 数据库表数据
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private void updateTheDataOfTheChildTable(final TableHead tableHead, final JSONObject tableDataJson) {
        // 如果是主表 还需要保存子表的数据
        String subTables = tableHead.getSubTableCheckList();
        // 判断一下防止空指针
        if (ConvertUtils.isNotEmpty(subTables)) {
            for (String subTableName : subTables.split(CommonConstant.COMMA)) {
                // 数据库表表信息
                TableHead subTableHead = this.serviceByTableHeadService.getOne(new LambdaQueryWrapper<TableHead>().eq(TableHead::getTableName, subTableName));
                if (subTableHead == null) {
                    continue;
                }
                // 数据库表字段信息
                List<TableFields> subTableFieldList = this.serviceByTableFieldsService.list(new LambdaQueryWrapper<TableFields>().eq(TableFields::getTableHeadId, subTableHead.getId()));
                // 这里有一步非常重要 需要获取子表字段对应设置外键的那个字段然后赋值
                String subLinkField = "",
                        subLinkValue = null;
                for (TableFields subTableField : subTableFieldList) {
                    if (ConvertUtils.isEmpty(subTableField.getMainField())) {
                        continue;
                    }
                    subLinkField = subTableField.getFieldName();
                    String mainField = subTableField.getMainField();
                    // 主子表关联字段取值， 做出 KEY 忽略大小写
                    if (tableDataJson.get(mainField.toLowerCase()) != null) {
                        // 小写
                        subLinkValue = tableDataJson.getString(mainField.toLowerCase());
                    }
                    if (tableDataJson.get(mainField.toUpperCase()) != null) {
                        // 大写
                        subLinkValue = tableDataJson.getString(mainField.toUpperCase());
                    }
                }
                // 删除从表数据
                if (ConvertUtils.isEmpty(subLinkValue)) {
                    continue;
                }
                deleteTableData(subTableName, subLinkField, subLinkValue);
                // 新增数据
                JSONArray jsonArray = tableDataJson.getJSONArray(subTableName);
                if (jsonArray == null || jsonArray.size() == 0) {
                    continue;
                }
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    if (subLinkValue != null) {
                        // 设置外键值
                        jsonObject.put(subLinkField, subLinkValue);
                    }
                    this.saveFormData(subTableName, subTableFieldList, jsonObject);
                }
            }
        }
    }

    /**
     * 保存树形表的数据
     *
     * @param tableHead     - 主表数据库表表信息
     * @param tableDataJson - 数据库表数据
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private void saveTreeFormData(final TableHead tableHead, final JSONObject tableDataJson) {
        String realTableName = FormUtil.getRealTableName(tableHead.getTableName());
        // 数据库表字段信息
        List<TableFields> tableFieldsList = this.serviceByTableFieldsService.list(new LambdaQueryWrapper<TableFields>().eq(TableFields::getTableHeadId, tableHead.getId()));
        for (TableFields tableFields : tableFieldsList) {
            // 如果是否有子节点不显示 则新增一个节点时设置为 0
            String treeIdFieldName = tableHead.getTreeIdFieldName();
            if (treeIdFieldName.equals(tableFields.getFieldName()) && CommonConstant.INTEGER_YES.equals(tableFields.getIsShowForm())) {
                tableFields.setIsShowForm(CommonConstant.INTEGER_YES);
                tableDataJson.put(treeIdFieldName, CommonConstant.ZERO);
                continue;
            }
            // 如果父id为空 则设置为 0 表示根节点
            String treeParentIdFieldName = tableHead.getTreeParentIdFieldName();
            if (treeParentIdFieldName.equals(tableFields.getFieldName()) && ConvertUtils.isEmpty(tableDataJson.get(treeParentIdFieldName))) {
                tableFields.setIsShowForm(CommonConstant.INTEGER_YES);
                tableDataJson.put(treeParentIdFieldName, CommonConstant.ZERO);
            }
        }
        // 表单数据保存 SQL 获取（默认id是主键并且为 IdWorker）
        Map<String, Object> formDataSaveStructuredQueryLanguage = FormUtil.getFormDataSaveStructuredQueryLanguage(realTableName, tableFieldsList, tableDataJson);
        boolean execute = this.serviceByTableIndexService.executeInsertStructuredQueryLanguage(formDataSaveStructuredQueryLanguage);
        assertThat(Boolean.TRUE).as("保存数据库表数据").isEqualTo(execute).isTrue();
        // 保存当前节点时设置父级节点为有子节点
        if (!CommonConstant.ZERO.equals(tableDataJson.getString(tableHead.getTreeParentIdFieldName()))) {
            String structureQueryLanguage = DataBaseConstant.SQL_UPDATE + realTableName + DataBaseConstant.SQL_SET + tableHead.getTreeIdFieldName() + DataBaseConstant.SPACE +
                    DataBaseConstant.EQUALS + DataBaseConstant.SPACE + DataBaseConstant.SINGLE_QUOTE + CommonConstant.ONE + DataBaseConstant.SINGLE_QUOTE +
                    DataBaseConstant.SQL_WHERE + DataBaseConstant.P_KEY + DataBaseConstant.SPACE + DataBaseConstant.EQUALS + DataBaseConstant.SPACE +
                    DataBaseConstant.SINGLE_QUOTE + tableDataJson.getString(tableHead.getTreeParentIdFieldName()) + DataBaseConstant.SINGLE_QUOTE;
            execute = this.serviceByTableIndexService.executeDataDefinitionLanguage(structureQueryLanguage);
            assertThat(Boolean.TRUE).as("保存当前节点时设置父级节点为有子节点").isEqualTo(execute).isTrue();
        }
    }

    /**
     * 更新树形表的数据
     *
     * @param tableHead     - 主表数据库表表信息
     * @param tableDataJson - 数据库表数据
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private void updateTreeFormData(final TableHead tableHead, final JSONObject tableDataJson) {
        // 获取真实数据库表表名
        String realTableName = FormUtil.getRealTableName(tableHead.getTableName());
        // 数据主键
        Long dataId = tableDataJson.getLong(DataBaseConstant.P_KEY);
        String structureQueryLanguage = DataBaseConstant.SQL_SELECT + DataBaseConstant.STAR + DataBaseConstant.SQL_FROM + realTableName + DataBaseConstant.SQL_WHERE + DataBaseConstant.P_KEY +
                DataBaseConstant.SPACE + DataBaseConstant.EQUALS + DataBaseConstant.SPACE + DataBaseConstant.SINGLE_QUOTE + dataId + DataBaseConstant.SINGLE_QUOTE;
        // 元数据
        Map<String, Object> metaData = this.serviceByTableIndexService.executeQueryStructuredQueryLanguage(structureQueryLanguage);
        // Map 的 key 转成小写（数据库大小写兼容问题）
        Map<String, Object> metaDataLower = FormUtil.transLowerCaseMapKey(metaData);
        // 元数据父级编号字段名
        String treeParentIdFieldName = tableHead.getTreeParentIdFieldName();
        // 元数据父级编号
        String metaParentId = metaDataLower.get(treeParentIdFieldName).toString();
        // 数据库表字段信息
        List<TableFields> tableFieldsList = this.serviceByTableFieldsService.list(new LambdaQueryWrapper<TableFields>().eq(TableFields::getTableHeadId, tableHead.getId()));
        for (TableFields tableFields : tableFieldsList) {
            // 如果父id为空 则设置为 0 表示根节点
            if (treeParentIdFieldName.equals(tableFields.getFieldName()) && ConvertUtils.isEmpty(tableDataJson.get(treeParentIdFieldName))) {
                tableFields.setIsShowForm(CommonConstant.INTEGER_YES);
                tableDataJson.put(treeParentIdFieldName, CommonConstant.ZERO);
            }
        }
        // 表单数据更新 SQL 获取（默认id是主键并且为 IdWorker）
        Map<String, Object> formDataSaveStructuredQueryLanguage = FormUtil.getFormDataEditStructuredQueryLanguage(realTableName, tableFieldsList, tableDataJson);
        boolean execute = this.serviceByTableIndexService.executeUpdateStructuredQueryLanguage(formDataSaveStructuredQueryLanguage);
        assertThat(Boolean.TRUE).as("更新数据库表数据").isEqualTo(execute).isTrue();
        if (!metaParentId.equals(tableDataJson.getString(treeParentIdFieldName))) {
            // 如果 原数据 的 父级ID 和 新数据 的 父级ID 不一致 那么求 老数据 的 父级ID 的子节点 COUNT
            if (!CommonConstant.ZERO.equals(metaParentId)) {
                structureQueryLanguage = DataBaseConstant.SQL_SELECT + DataBaseConstant.SQL_COUNT + DataBaseConstant.SQL_FROM + realTableName +
                        DataBaseConstant.SQL_WHERE + treeParentIdFieldName + DataBaseConstant.SPACE + DataBaseConstant.EQUALS + DataBaseConstant.SPACE +
                        DataBaseConstant.SINGLE_QUOTE + metaParentId + DataBaseConstant.SINGLE_QUOTE;
                Integer count = this.serviceByTableIndexService.executeCountStructuredQueryLanguage(structureQueryLanguage);
                if (count == null || count == 0) {
                    structureQueryLanguage = DataBaseConstant.SQL_UPDATE + realTableName + DataBaseConstant.SQL_SET + tableHead.getTreeIdFieldName() + DataBaseConstant.SPACE +
                            DataBaseConstant.EQUALS + DataBaseConstant.SPACE + DataBaseConstant.SINGLE_QUOTE + CommonConstant.ZERO + DataBaseConstant.SINGLE_QUOTE +
                            DataBaseConstant.SQL_WHERE + DataBaseConstant.P_KEY + DataBaseConstant.SPACE + DataBaseConstant.EQUALS + DataBaseConstant.SPACE +
                            DataBaseConstant.SINGLE_QUOTE + metaParentId + DataBaseConstant.SINGLE_QUOTE;
                    execute = this.serviceByTableIndexService.executeUpdateStructuredQueryLanguage(structureQueryLanguage);
                    assertThat(Boolean.TRUE).as("更新当前节点时设置父级节点为有子节点").isEqualTo(execute).isTrue();
                }
            }
            // 更新当前节点时设置父级节点为有子节点
            if (!CommonConstant.ZERO.equals(tableDataJson.getString(treeParentIdFieldName))) {
                structureQueryLanguage = DataBaseConstant.SQL_UPDATE + realTableName + DataBaseConstant.SQL_SET + tableHead.getTreeIdFieldName() + DataBaseConstant.SPACE +
                        DataBaseConstant.EQUALS + DataBaseConstant.SPACE + DataBaseConstant.SINGLE_QUOTE + CommonConstant.ZERO + DataBaseConstant.SINGLE_QUOTE +
                        DataBaseConstant.SQL_WHERE + DataBaseConstant.P_KEY + DataBaseConstant.SPACE + DataBaseConstant.EQUALS + DataBaseConstant.SPACE +
                        DataBaseConstant.SINGLE_QUOTE + tableDataJson.getString(treeParentIdFieldName) + DataBaseConstant.SINGLE_QUOTE;
                execute = this.serviceByTableIndexService.executeUpdateStructuredQueryLanguage(structureQueryLanguage);
                assertThat(Boolean.TRUE).as("更新当前节点时设置父级节点为有子节点").isEqualTo(execute).isTrue();
            }
        }
    }

    /**
     * 保存数据库表数据
     *
     * @param tableHead     - 主表数据库表表信息
     * @param tableDataJson - 数据库表数据
     * @param isCrazy       -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private void saveFormData(final TableHead tableHead, final JSONObject tableDataJson, final Boolean isCrazy) {
        String realTableName = FormUtil.getRealTableName(tableHead.getTableName());
        // 数据库表字段信息
        List<TableFields> tableFieldsList = this.serviceByTableFieldsService.list(new LambdaQueryWrapper<TableFields>().eq(TableFields::getTableHeadId, tableHead.getId()));
        if (isCrazy) {
            // tableDataJson.put(DataBaseConstant.P_KEY, IdWorker.getId());
            Map<String, Object> params = FormUtil.getCrazyFormDataSaveStructuredQueryLanguage(realTableName, tableFieldsList, tableDataJson);
            Boolean save = this.serviceByTableIndexService.executeInsertStructuredQueryLanguage(params);
            assertThat(Boolean.TRUE).as("保存数据库表数据").isEqualTo(save).isTrue();
        } else {
            saveFormData(realTableName, tableFieldsList, tableDataJson);
        }
    }

    /**
     * 更新数据库表数据
     *
     * @param tableHead     - 主表数据库表表信息
     * @param tableDataJson - 数据库表数据
     * @param isCrazy       -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private void updateFormData(final TableHead tableHead, final JSONObject tableDataJson, final Boolean isCrazy) {
        String realTableName = FormUtil.getRealTableName(tableHead.getTableName());
        // 数据库表字段信息
        List<TableFields> tableFieldsList = this.serviceByTableFieldsService.list(new LambdaQueryWrapper<TableFields>().eq(TableFields::getTableHeadId, tableHead.getId()));
        Map<String, Object> params;
        if (isCrazy) {
            params = FormUtil.getCrazyFormDataEditStructuredQueryLanguage(realTableName, tableFieldsList, tableDataJson);
        } else {
            params = FormUtil.getFormDataEditStructuredQueryLanguage(realTableName, tableFieldsList, tableDataJson);
        }
        assertThat(params).as("更新数据库表数据的SQL对象").isEmpty();
        Boolean update = this.serviceByTableIndexService.executeUpdateStructuredQueryLanguage(params);
        assertThat(Boolean.TRUE).as("更新数据库表数据").isEqualTo(update).isTrue();
    }

    /**
     * 如果是树节点 需要判断上级节点状态
     *
     * @param tableHead - 在线开发-数据库表表信息 PO
     * @param dataId    - 数据库表数据编号
     * @return Boolean -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private Boolean updateParentNode(final TableHead tableHead, final Long dataId) {
        boolean updateParentNode = Boolean.FALSE;
        if (CommonConstant.STATUS_OK.equals(tableHead.getIsTree())) {
            String tableName = FormUtil.getRealTableName(tableHead.getTableName());
            // 树形表单父 ID 字段
            String treeParentIdFieldName = tableHead.getTreeParentIdFieldName();
            // 查询数据库表的指定数据所有字段内容
            Map<String, Object> tableDataMap = this.serviceByTableIndexService.queryTableDataByTableNameAndDataId(tableName, dataId);
            // 确定数据 父 ID
            String parentId = null;
            if (tableDataMap.get(treeParentIdFieldName) != null && !CommonConstant.ZERO.equals(tableDataMap.get(treeParentIdFieldName))) {
                parentId = tableDataMap.get(treeParentIdFieldName).toString();
            } else if (tableDataMap.get(treeParentIdFieldName.toUpperCase()) != null && !CommonConstant.ZERO.equals(tableDataMap.get(treeParentIdFieldName.toUpperCase()))) {
                parentId = tableDataMap.get(treeParentIdFieldName.toUpperCase()).toString();
            }
            if (parentId != null) {
                // 查询子节点数量
                Integer numberOfChildNodes = this.serviceByTableIndexService.queryNumberOfChildNodes(tableName, treeParentIdFieldName, parentId);
                if (numberOfChildNodes == 1) {
                    String hasChild = tableHead.getTreeIdFieldName();
                    updateParentNode = this.serviceByTableIndexService.updateTreeNodeNoChild(tableName, hasChild, parentId);
                }
            }
        }
        return updateParentNode;
    }

    /**
     * 删除表的数据
     *
     * @param tableName - 数据库表表名称
     * @param linkField - 字段名称
     * @param linkValue - 字段值
     * @return Boolean -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private Boolean deleteTableData(final String tableName, final String linkField, final String linkValue) {
        boolean deleteTableData = Boolean.FALSE;
        if (linkValue != null && !CommonConstant.EMPTY.equals(linkValue)) {
            String[] arr = linkValue.split(CommonConstant.COMMA);
            StringBuilder stringBuilder = new StringBuilder();
            for (String str : arr) {
                if (str == null || CommonConstant.EMPTY.equals(str)) {
                    continue;
                }
                stringBuilder.append(DataBaseConstant.SINGLE_QUOTE).append(str).append(DataBaseConstant.SINGLE_QUOTE).append(DataBaseConstant.COMMA);
            }
            String temp = stringBuilder.toString();
            String structuredQueryLanguage = DataBaseConstant.SQL_DELETE + DataBaseConstant.SQL_FROM + FormUtil.getRealTableName(tableName) + DataBaseConstant.SQL_WHERE + linkField + DataBaseConstant.SQL_IN + DataBaseConstant.LEFT_BRACKET + temp.substring(0, temp.length() - 1) + DataBaseConstant.RIGHT_BRACKET;
            log.info("-- 删除 structuredQueryLanguage -->" + structuredQueryLanguage);
            deleteTableData = this.serviceByTableIndexService.executeDeleteStructuredQueryLanguage(structuredQueryLanguage);
        }
        return deleteTableData;
    }

    /**
     * 根据数据主键删除表的数据
     *
     * @param tableName - 数据库表表名称
     * @param dataId    - 唯一标识
     * @return Boolean -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private Boolean deleteTableDataById(final String tableName, final Long dataId) {
        return this.deleteTableData(tableName, DataBaseConstant.P_KEY_FIELD, String.valueOf(dataId));
    }

    /**
     * 自动删除主表跟子表的数据
     *
     * @param tableHead - 数据库表表信息
     * @param dataId    - 主表数据编号
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private void deleteAutoListMainAndSub(final TableHead tableHead, final Long dataId) {
        if (CommonConstant.TABLE_TYPE_1.equals(tableHead.getTableType())) {
            Long headId = tableHead.getId();
            String headName = tableHead.getTableName();
            // 子表名key
            String tableName = "tableName";
            // 子表外键字段key
            String linkField = "linkField";
            // 子表外键字段值key(多值，逗号分隔)
            String linkValueString = "linkValueString";
            // 子表外键关联主表的字段key
            String mainField = "mainField";
            // 外键集合 List, 找出 tableName  linkFiled  mainField
            List<Map<String, String>> ls = new ArrayList<>();
            // 子表数据删除逻辑
            String subTables = tableHead.getSubTableCheckList();
            if (ConvertUtils.isNotEmpty(subTables)) {
                for (String getTableName : subTables.split(CommonConstant.COMMA)) {
                    // 查询子表配置
                    TableHead subTable = this.serviceByTableHeadService.getOne(new LambdaQueryWrapper<TableHead>().eq(TableHead::getTableName, getTableName));
                    if (subTable == null) {
                        continue;
                    }
                    //查询子表配置的外键字段
                    List<TableFields> subFieldList = this.serviceByTableFieldsService.list(new LambdaQueryWrapper<TableFields>().eq(TableFields::getTableHeadId, subTable.getId()).eq(TableFields::getMainTable, tableHead.getTableName()));
                    if (subFieldList == null || subFieldList.size() == 0) {
                        continue;
                    }
                    // TODO：This 目前外键只支持一个，不支持组合外键
                    TableFields subField = subFieldList.get(0);
                    Map<String, String> map = new HashMap<>(4);
                    // 子表字段名字
                    map.put(linkField, subField.getFieldName());
                    // 外键关联的主表字段
                    map.put(mainField, subField.getMainField());
                    // 子表表名
                    map.put(tableName, getTableName);
                    map.put(linkValueString, "");
                    ls.add(map);
                }
                // 查询主表的字段配置
                List<TableFields> fieldList = this.serviceByTableFieldsService.list(new LambdaQueryWrapper<TableFields>().eq(TableFields::getTableHeadId, headId));
                String structureQueryLanguage = FormUtil.getQueryFormDataByIdStructuredQueryLanguage(headName, fieldList, String.valueOf(dataId));
                // 获取主表数据
                Map<String, Object> tableDataMap = this.serviceByTableIndexService.executeQueryStructuredQueryLanguage(structureQueryLanguage);
                for (Map<String, String> temp : ls) {
                    Object linkValue = tableDataMap.get(temp.get(mainField).toLowerCase());
                    if (linkValue == null) {
                        linkValue = tableDataMap.get(temp.get(mainField).toUpperCase());
                    }
                    if (linkValue == null) {
                        continue;
                    }
                    String newLinkValue = temp.get(linkValueString) + linkValue + DataBaseConstant.COMMA;
                    temp.put(linkValueString, newLinkValue);
                }
                // 删除子表数据
                for (Map<String, String> temp : ls) {
                    boolean deleteTableData = deleteTableData(temp.get(tableName), temp.get(linkField), temp.get(linkValueString));
                    assertThat(Boolean.TRUE).as("删除子表数据").isEqualTo(deleteTableData).isTrue();
                }
            }
            // 删除主表数据
            boolean deleteTableDataById = deleteTableDataById(tableHead.getTableName(), dataId);
            assertThat(Boolean.TRUE).as("删除主表数据").isEqualTo(deleteTableDataById).isTrue();
        }
    }

    /**
     * 执行 StructuredQueryLanguage 增强
     *
     * @param enhanceStructuredQueryLanguage - StructuredQueryLanguage 增强
     * @param tableDataJson                  - 数据库表数据
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    private void executeStructureQueryLanguageEnhanceInterface(final FormEnhanceStructuredQueryLanguage enhanceStructuredQueryLanguage, final JSONObject tableDataJson) {
        if (enhanceStructuredQueryLanguage != null) {
            String structuredQueryLanguageArrayString = FormUtil.formatStructuredQueryLanguage(enhanceStructuredQueryLanguage.getStructuredQueryLanguageContent(), tableDataJson);
            String[] structuredQueryLanguageArray = structuredQueryLanguageArrayString.split(DataBaseConstant.SEMICOLON);
            for (String structuredQueryLanguage : structuredQueryLanguageArray) {
                if (structuredQueryLanguage == null || CommonConstant.EMPTY.equals(structuredQueryLanguage.toLowerCase().trim())) {
                    continue;
                }
                log.info("Online StructuredQueryLanguage 增强： " + structuredQueryLanguage);
                Boolean executeStructureQueryLanguageEnhanceInterface = this.serviceByTableIndexService.executeDataDefinitionLanguage(structuredQueryLanguage);
                assertThat(Boolean.TRUE).as("删除数据库表").isEqualTo(executeStructureQueryLanguageEnhanceInterface).isTrue();
            }
        }
    }

    /**
     * 获取列表页面元素接口
     *
     * @param id - 数据库表表编号
     * @return Result - List<FormButtonVO> 数据库表自定义按钮
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2021/1/11 11:07
     */
    public CommonResponse queryListPageElement(final Long id) {
        // 1.数据库表
        TableHead tableHead = this.serviceByTableHeadService.getById(id);
        assertThat(tableHead).as("在线开发-数据库表表信息").isNotNull();
        // 2.构建列表页面元素对象
        ListPageElementVO listPageElement = TableHeadConverter.INSTANCE.getListPageElement(tableHead);
        // 3.添加 自定义按钮
        List<FormButton> formButtonList = serviceByFormButtonService.list(Wrappers.<FormButton>lambdaQuery().eq(FormButton::getTableHeadId, tableHead.getId()).eq(FormButton::getButtonStatus, CommonConstant.STATUS_OK));
        listPageElement.setFormButtonList(FormButtonConverter.INSTANCE.getReturnValue(formButtonList));
        // 4.权限过滤后的 数据库表字段信息
        List<TableFields> tableFieldPermissionFilteringList = this.serviceByTableFieldsService.queryTableFieldPermissionFilteringListByTableHeadId(tableHead.getId());
        if (!tableFieldPermissionFilteringList.isEmpty()) {
            // 5.获取列表页面字段元素
            getListPageTableFieldElement(listPageElement, tableFieldPermissionFilteringList);
        }
        // 6.添加 JavaScript 增强
        FormEnhanceJavaScript formEnhanceJavaScripts = serviceByFormEnhanceJavaScriptService.getOne(Wrappers.<FormEnhanceJavaScript>lambdaQuery().eq(FormEnhanceJavaScript::getTableHeadId, id).eq(FormEnhanceJavaScript::getJavaScriptType, CommonConstant.ENHANCE_LIST), Boolean.FALSE);
        String javaScript = EnhanceJavaScriptUtil.overFinalWriteJavaScript(formEnhanceJavaScripts.getJavaScriptContent(), formButtonList);
        listPageElement.setJavaScriptEnhance(javaScript);
        return new CommonResponse(listPageElement);
    }

    /**
     * 查询数据库表自定义JS接口
     *
     * @param id             - 数据库表表编号
     * @param javaScriptType - JS类型
     * @return Result - List<FormButtonVO> 数据库表自定义JS
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    public CommonResponse queryJavaScript(final Long id, final String javaScriptType) {
        FormEnhanceJavaScript formEnhanceJavaScripts = serviceByFormEnhanceJavaScriptService.getOne(Wrappers.<FormEnhanceJavaScript>lambdaQuery().eq(FormEnhanceJavaScript::getTableHeadId, id).eq(ConvertUtils.isNotEmpty(javaScriptType), FormEnhanceJavaScript::getJavaScriptType, javaScriptType), Boolean.FALSE);
        return new CommonResponse(FormEnhanceJavaScriptConverter.INSTANCE.getReturnValue(formEnhanceJavaScripts));
    }

    /**
     * 查询数据库表自定义Java接口
     *
     * @param id         - 数据库表表编号
     * @param buttonCode - 自定义按钮
     * @return Result - List<FormEnhanceStructuredQueryLanguageVO> 数据库表自定义Java
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    public CommonResponse queryJava(final Long id, final String buttonCode) {
        FormEnhanceJava formEnhanceJava = serviceByFormEnhanceJavaService.getOne(Wrappers.<FormEnhanceJava>lambdaQuery().eq(FormEnhanceJava::getTableHeadId, id).eq(ConvertUtils.isNotEmpty(buttonCode), FormEnhanceJava::getButtonCode, buttonCode), Boolean.FALSE);
        return new CommonResponse(FormEnhanceJavaConverter.INSTANCE.getReturnValue(formEnhanceJava));
    }

    /**
     * 查询数据库表自定义SQL接口
     *
     * @param id         - 数据库表表编号
     * @param buttonCode - 自定义按钮
     * @return Result - List<FormEnhanceStructuredQueryLanguageVO> 数据库表自定义SQL
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    public CommonResponse queryStructuredQueryLanguage(final Long id, final String buttonCode) {
        FormEnhanceStructuredQueryLanguage formEnhanceStructuredQueryLanguage = serviceByFormEnhanceStructuredQueryLanguageService.getOne(Wrappers.<FormEnhanceStructuredQueryLanguage>lambdaQuery().eq(FormEnhanceStructuredQueryLanguage::getTableHeadId, id).eq(ConvertUtils.isNotEmpty(buttonCode), FormEnhanceStructuredQueryLanguage::getButtonCode, buttonCode), Boolean.FALSE);
        return new CommonResponse(FormEnhanceStructuredQueryLanguageConverter.INSTANCE.getReturnValue(formEnhanceStructuredQueryLanguage));
    }

    /**
     * 分页查询数据库表数据接口
     *
     * @param pagingQueryData - 数据库表数据分页查询对象
     * @return Result - 数据库表数据
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    public CommonResponse pagingQueryDataListByParameter(final PagingQueryDataDTO pagingQueryData) {
        // 1.数据库表表信息
        TableHead tableHead = this.serviceByTableHeadService.getById(pagingQueryData.getId());
        // 对象断言-是否非空
        assertThat(tableHead).as("在线开发-数据库表表信息-分页查询数据库表数据").isNotNull();
        String realTableName = FormUtil.getRealTableName(tableHead.getTableName());
        // 2.权限过滤后的 数据库表字段信息
        List<TableFields> tableFieldPermissionFilteringList = this.serviceByTableFieldsService.queryTableFieldPermissionFilteringListByTableHeadId(pagingQueryData.getId());
        // 3.列表展示的 数据库表字段信息
        List<TableFields> tableFieldsShowList = tableFieldPermissionFilteringList.stream()
                // 列表是否显示（0否 1是）
                .filter(tableFields -> CommonConstant.INTEGER_YES.equals(tableFields.getIsShowList()))
                // 外键主表名、外键主键字段 都不为空
                .filter(tableFields -> ConvertUtils.isNotEmpty(tableFields.getMainTable()) && ConvertUtils.isNotEmpty(tableFields.getMainField()))
                // 排序
                .sorted(Comparator.comparing(TableFields::getSortOrder))
                // 转换成为 List
                .collect(Collectors.toList());
        // 4.获取查询 SQL
        StringBuffer structuredQueryLanguage = new StringBuffer();
        // 基础 SQL（WHERE 关键字 之前的部分）
        FormUtil.getAutoListBaseStructuredQueryLanguage(tableHead.getTableName(), tableFieldsShowList, structuredQueryLanguage);
        // 数据库表表数据查询条件
        Map<String, Object> queryConditions = pagingQueryData.getQueryConditions();
        // 查询条件 SQL（数据权限）
        String conditionStructuredQueryLanguage = FormUtil.getAutoListConditionStructuredQueryLanguage(tableFieldsShowList, queryConditions);
        // 高级查询 SQL（页面动态选择条件，支持主子表查询）
        String superQueryStructuredQueryLanguage = FormUtil.getAutoListSuperQueryStructuredQueryLanguage(queryConditions);
        // 拼接条件 SQL
        structuredQueryLanguage.append(DataBaseConstant.SQL_WHERE_TRUE).append(conditionStructuredQueryLanguage).append(superQueryStructuredQueryLanguage);
        // 排序字段
        List<SortField> sortFieldList = pagingQueryData.getSortFieldList();
        if (pagingQueryData.getWhetherToPage()) {
            // 5.1分页操作
            Page<Map<String, Object>> pageQuery = new Page<>(pagingQueryData.getPageNumber(), pagingQueryData.getPageSize());
            List<OrderItem> orderItemList = SysDictConverter.INSTANCE.getOrderItemList(sortFieldList);
            pageQuery.addOrder(orderItemList);
            log.info("分页查询 StructuredQueryLanguage : {} ", structuredQueryLanguage.toString());
            pageQuery = this.serviceByTableIndexService.executePagingQueryTableDataListByStructuredQueryLanguage(pageQuery, structuredQueryLanguage.toString());
            pageQuery.setRecords(FormUtil.toLowerCasePageList(pageQuery.getRecords()));
            return new CommonResponse(pageQuery);
        } else {
            // 5.2列表不分页操作
            for (int i = 0; i < sortFieldList.size(); i++) {
                SortField sortField = sortFieldList.get(i);
                // 字段名
                String fieldsName = sortField.getFieldsName();
                if (0 == i) {
                    // 排序关键字
                    structuredQueryLanguage.append(DataBaseConstant.SQL_ORDER);
                }
                // 将驼峰命名转化成下划线
                String underscoreFieldsName = tableHead.getTableName() + ConvertUtils.camelToUnderline(fieldsName);
                structuredQueryLanguage.append(underscoreFieldsName).append(DataBaseConstant.SPACE);
                if (sortField.getAsc()) {
                    // 升序
                    structuredQueryLanguage.append(DataBaseConstant.SQL_ASC);
                } else {
                    // 降序
                    structuredQueryLanguage.append(DataBaseConstant.SQL_DESC);
                }
                // 逗号隔开
                if (sortFieldList.size() - 1 > i) {
                    structuredQueryLanguage.append(DataBaseConstant.COMMA);
                }
            }
            log.info("不分页查询 StructuredQueryLanguage : {} ", structuredQueryLanguage.toString());
            List<Map<String, Object>> tableDataList = this.serviceByTableIndexService.executeQueryTableDataListByStructuredQueryLanguage(structuredQueryLanguage.toString());
            return new CommonResponse(FormUtil.toLowerCasePageList(tableDataList));
        }
    }

    /**
     * 查询数据库表数据添加字段接口
     *
     * @param id - 数据库表表编号
     * @return Result - List<FormColumnVO> 数据库表数据添加字段
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    public CommonResponse queryDataAddField(final Long id) {
        // 权限过滤后的 数据库表字段信息
        List<TableFields> tableFieldsList = this.serviceByTableFieldsService.queryTableFieldPermissionFilteringListByTableHeadId(id);
        // 字段的页面属性
        List<TableFieldsVO> formColumnList = new ArrayList<>();
        if (!tableFieldsList.isEmpty()) {
            formColumnList = TableFieldsConverter.INSTANCE.getReturnValue(tableFieldsList);
        }
        return new CommonResponse(formColumnList);
    }

    /**
     * 添加数据库表数据接口
     *
     * @param dataAdd - 添加数据库表数据
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    public BaseResponse addData(final DataAddDTO dataAdd) {
        // TODO:This 多数据源（不能用 @Transactional(rollbackFor = Exception.class)）
        TableHead tableHead = this.serviceByTableHeadService.getById(dataAdd.getId());
        // 权限过滤后的 数据库表字段信息
        List<TableFields> tableFieldsList = this.serviceByTableFieldsService.queryTableFieldPermissionFilteringListByTableHeadId(dataAdd.getId());
        this.addTableDataVerification(dataAdd, tableHead, tableFieldsList);
        // 查询 添加 的 start 事件类型 Java 增强
        FormEnhanceJava formEnhanceJava = this.serviceByFormEnhanceJavaService.getOne(Wrappers.<FormEnhanceJava>lambdaQuery().eq(FormEnhanceJava::getActiveStatus, CommonConstant.STATUS_OK)
                .eq(FormEnhanceJava::getButtonCode, ButtonCodeEnum.ADD.getValue()).eq(FormEnhanceJava::getTableHeadId, tableHead.getId())
                .eq(FormEnhanceJava::getEvent, CommonConstant.EVENT_START)
        );
        // 数据库表表数据
        JSONObject tableDataJson = dataAdd.getTableDataJson();
        if (formEnhanceJava != null) {
            // 执行 添加 的 start 事件类型 Java 增强
            EnhanceJavaUtil.executeJavaEnhanceInterface(tableHead, formEnhanceJava, tableDataJson);
            // 执行完成 start 事件类型 Java 增强  立即获取 end 事件类型 Java 增强  供给下次执行
            formEnhanceJava = this.serviceByFormEnhanceJavaService.getOne(Wrappers.<FormEnhanceJava>lambdaQuery().eq(FormEnhanceJava::getActiveStatus, CommonConstant.STATUS_OK)
                    .eq(FormEnhanceJava::getButtonCode, ButtonCodeEnum.ADD.getValue()).eq(FormEnhanceJava::getTableHeadId, tableHead.getId())
                    .eq(FormEnhanceJava::getEvent, CommonConstant.EVENT_END)
            );
            assertThat(Boolean.TRUE).as("查询不到 添加 的 end 事件类型 Java 增强").isEqualTo(formEnhanceJava != null).isTrue();
        }
        // 主表
        if (CommonConstant.TABLE_TYPE_1.equals(tableHead.getTableType())) {
            // 如果是主表 还需要保存子表的数据
            saveTheDataOfTheChildTable(tableHead, tableDataJson);
        }
        // 如果是 TREE 则新增时赋值：是否子节点
        if (CommonConstant.INTEGER_YES.equals(tableHead.getIsTree())) {
            this.saveTreeFormData(tableHead, tableDataJson);
        } else {
            this.saveFormData(tableHead, tableDataJson, Boolean.FALSE);
        }
        // 执行 SQL 增强
        LambdaQueryWrapper<FormEnhanceStructuredQueryLanguage> query = new LambdaQueryWrapper<FormEnhanceStructuredQueryLanguage>()
                .eq(FormEnhanceStructuredQueryLanguage::getButtonCode, ButtonCodeEnum.ADD.getValue())
                .eq(FormEnhanceStructuredQueryLanguage::getTableHeadId, tableHead.getId());
        FormEnhanceStructuredQueryLanguage enhanceStructuredQueryLanguage = this.serviceByFormEnhanceStructuredQueryLanguageService.getOne(query);
        this.executeStructureQueryLanguageEnhanceInterface(enhanceStructuredQueryLanguage, tableDataJson);
        // 执行 添加 的 end 事件类型 Java 增强
        EnhanceJavaUtil.executeJavaEnhanceInterface(tableHead, formEnhanceJava, tableDataJson);
        return new CommonResponse<>();
    }

    /**
     * 删除数据库表数据接口
     *
     * @param id     - 数据库表表编号
     * @param dataId - 数据库表数据编号
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    public BaseResponse deleteData(final Long id, final Long dataId) {
        // TODO:This 多数据源（不能用 @Transactional(rollbackFor = Exception.class)）
        TableHead tableHead = this.serviceByTableHeadService.getById(id);
        // 对象断言-是否非空
        assertThat(tableHead).as("在线开发-数据库表表信息").isNotNull();
        String realTableName = FormUtil.getRealTableName(tableHead.getTableName());
        // 查询数据库表的指定数据所有字段内容
        Map<String, Object> tableDataMap = this.serviceByTableIndexService.queryTableDataByTableNameAndDataId(realTableName, dataId);
        assertThat(tableDataMap).as("在线开发-数据库表表信息").isNotEmpty();
        // 查询 删除 的 start 事件类型 Java 增强
        FormEnhanceJava formEnhanceJava = this.serviceByFormEnhanceJavaService.getOne(Wrappers.<FormEnhanceJava>lambdaQuery().eq(FormEnhanceJava::getActiveStatus, CommonConstant.STATUS_OK)
                .eq(FormEnhanceJava::getButtonCode, ButtonCodeEnum.DELETE.getValue()).eq(FormEnhanceJava::getTableHeadId, tableHead.getId())
                .eq(FormEnhanceJava::getEvent, CommonConstant.EVENT_START)
        );
        JSONObject tableDataJson = JSONObject.parseObject(JSON.toJSONString(tableDataMap));
        if (formEnhanceJava != null) {
            // 执行 删除 的 start 事件类型 Java 增强
            EnhanceJavaUtil.executeJavaEnhanceInterface(tableHead, formEnhanceJava, tableDataJson);
            // 执行完成 start 事件类型 Java 增强  立即获取 end 事件类型 Java 增强  供给下次执行
            formEnhanceJava = this.serviceByFormEnhanceJavaService.getOne(Wrappers.<FormEnhanceJava>lambdaQuery().eq(FormEnhanceJava::getActiveStatus, CommonConstant.STATUS_OK)
                    .eq(FormEnhanceJava::getButtonCode, ButtonCodeEnum.DELETE.getValue()).eq(FormEnhanceJava::getTableHeadId, tableHead.getId())
                    .eq(FormEnhanceJava::getEvent, CommonConstant.EVENT_END)
            );
            assertThat(Boolean.TRUE).as("查询不到 删除 的 end 事件类型 Java 增强").isEqualTo(formEnhanceJava != null).isTrue();
        }
        // 如果是树节点 需要判断上级节点状态
        boolean updateParentNode = this.updateParentNode(tableHead, dataId);
        assertThat(Boolean.TRUE).as("更新上级节点状态").isEqualTo(updateParentNode).isTrue();
        if (CommonConstant.TABLE_TYPE_1.equals(tableHead.getTableType())) {
            // 删除主表跟子表的数据
            this.deleteAutoListMainAndSub(tableHead, dataId);
        } else {
            String structureQueryLanguage = DataBaseConstant.SQL_DELETE + DataBaseConstant.SQL_FROM + realTableName + DataBaseConstant.SQL_WHERE + DataBaseConstant.P_KEY_FIELD + DataBaseConstant.SPACE + DataBaseConstant.EQUALS + DataBaseConstant.SPACE + DataBaseConstant.SINGLE_QUOTE + dataId + DataBaseConstant.SINGLE_QUOTE;
            this.serviceByTableIndexService.executeDeleteStructuredQueryLanguage(structureQueryLanguage);
        }
        // 执行 SQL 增强
        LambdaQueryWrapper<FormEnhanceStructuredQueryLanguage> query = new LambdaQueryWrapper<FormEnhanceStructuredQueryLanguage>()
                .eq(FormEnhanceStructuredQueryLanguage::getButtonCode, ButtonCodeEnum.DELETE.getValue())
                .eq(FormEnhanceStructuredQueryLanguage::getTableHeadId, tableHead.getId());
        FormEnhanceStructuredQueryLanguage enhanceStructuredQueryLanguage = this.serviceByFormEnhanceStructuredQueryLanguageService.getOne(query);
        this.executeStructureQueryLanguageEnhanceInterface(enhanceStructuredQueryLanguage, tableDataJson);
        // 执行 删除 的 end 事件类型 Java 增强
        EnhanceJavaUtil.executeJavaEnhanceInterface(tableHead, formEnhanceJava, tableDataJson);
        return new CommonResponse<>();
    }

    /**
     * 查询数据库表数据信息接口
     *
     * @param id     - 数据库表表编号
     * @param dataId - 数据库表数据编号
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    public CommonResponse queryDataById(final Long id, final String dataId) {
        // 1.数据库表表信息
        TableHead tableHead = this.serviceByTableHeadService.getById(id);
        // 对象断言-是否非空
        assertThat(tableHead).as("在线开发-数据库表表信息-主键查询数据库表数据").isNotNull();
        // 2.权限过滤后的 数据库表字段信息
        List<TableFields> tableFieldPermissionFilteringList =
                this.serviceByTableFieldsService.queryTableFieldPermissionFilteringListByTableHeadId(tableHead.getId()).stream()
                        // 过滤 表单是否显示（0否 1是）
                        .filter(tableFields -> CommonConstant.INTEGER_YES.equals(tableFields.getIsShowForm()))
                        // 排序
                        .sorted(Comparator.comparing(TableFields::getSortOrder))
                        // 转换成为 List
                        .collect(Collectors.toList());
        String structuredQueryLanguage = FormUtil.getQueryFormDataByIdStructuredQueryLanguage(tableHead.getTableName(), tableFieldPermissionFilteringList, dataId);
        Map<String, Object> tableData = this.serviceByTableIndexService.executeQueryStructuredQueryLanguage(structuredQueryLanguage);
        if (CommonConstant.TABLE_TYPE_1.equals(tableHead.getTableType())) {
            // 3.如果是主表 则还需要查询子表的数据 查询子表数据 需找到关联字段赋值
            String subTable = tableHead.getSubTableCheckList();
            if (ConvertUtils.isNotEmpty(subTable)) {
                for (String subTableName : subTable.split(CommonConstant.COMMA)) {
                    // 3.1。数据库表子表信息
                    TableHead subTableHead = this.serviceByTableHeadService.getOne(new LambdaQueryWrapper<TableHead>().eq(TableHead::getTableName, subTableName));
                    if (ConvertUtils.isEmpty(subTableHead)) {
                        continue;
                    }
                    // 3.2.权限过滤后的 数据库表子表字段信息
                    List<TableFields> subTableFieldPermissionFilteringList =
                            this.serviceByTableFieldsService.queryTableFieldPermissionFilteringListByTableHeadId(subTableHead.getId()).stream()
                                    // 过滤 表单是否显示（0否 1是）
                                    .filter(tableFields -> CommonConstant.INTEGER_YES.equals(tableFields.getIsShowForm()))
                                    // 排序
                                    .sorted(Comparator.comparing(TableFields::getSortOrder))
                                    // 转换成为 List
                                    .collect(Collectors.toList());
                    String subLinkField = "", subLinkValue = null;
                    for (TableFields tableFields : subTableFieldPermissionFilteringList) {
                        if (ConvertUtils.isEmpty(tableFields.getMainField())) {
                            continue;
                        }
                        subLinkField = tableFields.getFieldName();
                        String mainField = tableFields.getMainField();
                        // 预防空指针
                        if (ConvertUtils.isEmpty(tableData.get(mainField))) {
                            subLinkValue = tableData.get(mainField.toUpperCase()).toString();
                        } else {
                            subLinkValue = tableData.get(mainField).toString();
                        }
                    }
                    subTableName = subTableHead.getTableName();
                    String subTableStructuredQueryLanguage = FormUtil.getQueryFormDataByParameterStructuredQueryLanguage(subTableName, subTableFieldPermissionFilteringList, subLinkField, subLinkValue);
                    List<Map<String, Object>> subTableList = this.serviceByTableIndexService.executeQueryTableDataListByStructuredQueryLanguage(subTableStructuredQueryLanguage);
                    if (subTableList.isEmpty()) {
                        tableData.put(subTableName, new String[]{});
                    } else {
                        tableData.put(subTableName, FormUtil.toLowerCasePageList(subTableList));
                    }
                }
            }
        }
        return new CommonResponse<>(FormUtil.transLowerCaseMapKey(tableData));
    }

    /**
     * 修改数据库表数据接口
     *
     * @param dataUpdate - 数据库表数据字段查询对象
     * @return Result -
     * @author XinLau
     * @creed The only constant is change ! ! !
     * @since 2020/10/6 11:07
     */
    public BaseResponse updateData(final DataUpdateDTO dataUpdate) {
        // TODO:This 多数据源（不能用 @Transactional(rollbackFor = Exception.class)）
        TableHead tableHead = this.serviceByTableHeadService.getById(dataUpdate.getId());
        // 权限过滤后的 数据库表字段信息
        List<TableFields> tableFieldsList = this.serviceByTableFieldsService.queryTableFieldPermissionFilteringListByTableHeadId(dataUpdate.getId());
        this.updateTableDataVerification(dataUpdate, tableHead, tableFieldsList);
        // 查询 编辑 的 start 事件类型 Java 增强
        FormEnhanceJava formEnhanceJava = this.serviceByFormEnhanceJavaService.getOne(Wrappers.<FormEnhanceJava>lambdaQuery().eq(FormEnhanceJava::getActiveStatus, CommonConstant.STATUS_OK)
                .eq(FormEnhanceJava::getButtonCode, ButtonCodeEnum.EDIT.getValue()).eq(FormEnhanceJava::getTableHeadId, tableHead.getId())
                .eq(FormEnhanceJava::getEvent, CommonConstant.EVENT_START)
        );
        // 数据库表表数据
        JSONObject tableDataJson = dataUpdate.getTableDataJson();
        if (formEnhanceJava != null) {
            // 执行 编辑 的 start 事件类型 Java 增强
            EnhanceJavaUtil.executeJavaEnhanceInterface(tableHead, formEnhanceJava, tableDataJson);
            // 执行完成 start 事件类型 Java 增强  立即获取 end 事件类型 Java 增强  供给下次执行
            formEnhanceJava = this.serviceByFormEnhanceJavaService.getOne(Wrappers.<FormEnhanceJava>lambdaQuery().eq(FormEnhanceJava::getActiveStatus, CommonConstant.STATUS_OK)
                    .eq(FormEnhanceJava::getButtonCode, ButtonCodeEnum.EDIT.getValue()).eq(FormEnhanceJava::getTableHeadId, tableHead.getId())
                    .eq(FormEnhanceJava::getEvent, CommonConstant.EVENT_END)
            );
            assertThat(Boolean.TRUE).as("查询不到 编辑 的 end 事件类型 Java 增强").isEqualTo(formEnhanceJava != null).isTrue();
        }
        // 主表
        if (CommonConstant.TABLE_TYPE_1.equals(tableHead.getTableType())) {
            // 如果是主表 还需要保存子表的数据
            updateTheDataOfTheChildTable(tableHead, tableDataJson);
        }
        // 如果是 TREE 则新增时赋值：是否子节点
        if (CommonConstant.INTEGER_YES.equals(tableHead.getIsTree())) {
            this.updateTreeFormData(tableHead, tableDataJson);
        } else {
            this.updateFormData(tableHead, tableDataJson, Boolean.FALSE);
        }
        // 执行 SQL 增强
        LambdaQueryWrapper<FormEnhanceStructuredQueryLanguage> query = new LambdaQueryWrapper<FormEnhanceStructuredQueryLanguage>()
                .eq(FormEnhanceStructuredQueryLanguage::getButtonCode, ButtonCodeEnum.EDIT.getValue())
                .eq(FormEnhanceStructuredQueryLanguage::getTableHeadId, tableHead.getId());
        FormEnhanceStructuredQueryLanguage enhanceStructuredQueryLanguage = this.serviceByFormEnhanceStructuredQueryLanguageService.getOne(query);
        this.executeStructureQueryLanguageEnhanceInterface(enhanceStructuredQueryLanguage, tableDataJson);
        // 执行 添加 的 end 事件类型 Java 增强
        EnhanceJavaUtil.executeJavaEnhanceInterface(tableHead, formEnhanceJava, tableDataJson);
        return new CommonResponse<>();
    }

}